iT邦幫忙

0

PascalVOC 轉 Yolo標籤格式 (上) (範例程式碼)

  • 分享至 

  • xImage
  •  

完整程式碼!

https://github.com/yu-ken0207/PascalVOCtoYolo

將Pascal VOC格式的標註轉換為YOLO格式

要將Pascal VOC格式的標註轉換為YOLO格式,您可以按照以下步驟進行:

1. 理解兩種格式的區別

  • Pascal VOC格式:標註信息存儲在XML文件中,包含對象的類別和邊界框坐標。邊界框以像素為單位,使用左上角和右下角坐標表示,即xminyminxmaxymax
  • YOLO格式:標註信息存儲在文本文件中,每行代表一個對象,格式如下:
<class_id> <x_center> <y_center> <width> <height>

其中,x_center、y_center、width、height都是相對於圖像寬度和高度的正規化的值,範圍在0到1之間。

2. 轉換步驟

對於每個標註對象,執行以下步驟:

獲取圖像尺寸(寬度和高度):

  • image_width
  • image_height

提取邊界框坐標:

  • xmin
  • ymin
  • xmax
  • ymax

計算邊界框的寬度和高度:

bbox_width = xmax - xmin
bbox_height = ymax - ymin

計算邊界框中心點坐標:

x_center = xmin + (bbox_width / 2)
y_center = ymin + (bbox_height / 2)

正歸化座標:

x_center_norm = x_center / image_width
y_center_norm = y_center / image_height
bbox_width_norm = bbox_width / image_width
bbox_height_norm = bbox_height / image_height

獲取類別ID:

  • 將類別名稱映射為整數ID(從0開始)。

3. 範例程式碼

使用此資料集為例
Monkey, Cat and Dog detection
https://www.kaggle.com/datasets/tarunbisht11/yolo-animal-detection-small/data

Pascal VOC 格式:

  • 將 Pascal VOC 格式的標註文件(XML)轉換為 YOLO 格式的標註文件(TXT)
    https://ithelp.ithome.com.tw/upload/images/20241021/20170078eVbjnZel0s.png

在使用yolo進行訓練時需要使用以下格式:

https://ithelp.ithome.com.tw/upload/images/20241021/20170078uY7mC0YuzT.png

1. 匯入所需的模組

import os
import xml.etree.ElementTree as ET
  • os:提供與作業系統互動的功能,例如檔案和目錄操作。
  • xml.etree.ElementTree:Python 內建的 XML 解析器,用來處理 XML 文件中的結構與數據。

2. 定義轉換函數

def convert_bbox(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[2]) / 2.0 - 1
    y = (box[1] + box[3]) / 2.0 - 1
    w = box[2] - box[0]
    h = box[3] - box[1]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)
  • convert_bbox(size, box):這個函數將 XML 標註的邊界框轉換為 YOLO 格式。
  • size:圖像的寬度和高度。
  • box:包含 Pascal VOC 格式的邊界框,四個數值分別是左上角和右下角的 (xmin, ymin, xmax, ymax)。
  • 公式計算:
    中心座標 (x, y) 和寬高 (w, h) 會根據 YOLO 的要求進行歸一化(相對於圖像尺寸)。

3. 設定資料夾路徑

xml_folder = 'C:/Users/ken50/OneDrive/桌面/yolo-animal-detection-small/test'
txt_folder = 'C:/Users/ken50/OneDrive/桌面/yolo-animal-detection-small/test'

xml_folder:存放 Pascal VOC 格式標註文件的資料夾路徑。
txt_folder:存放轉換為 YOLO 格式後的標註文件的資料夾路徑。

4. 檢查並建立 TXT 資料夾

if not os.path.exists(txt_folder):
    os.makedirs(txt_folder)

檢查 txt_folder 是否存在。如果不存在,則建立這個資料夾,確保轉換後的 TXT 標註可以被儲存。

5. 定義類別名稱

classes = ["cat", "monkey", "dog"]

定義類別清單,這些類別名稱必須與 YAML 文件中的類別名稱一致,並且順序也要保持一致。

6. 遍歷 XML 文件

for file in os.listdir(xml_folder):
    if file.endswith(".xml"):
        tree = ET.parse(os.path.join(xml_folder, file))
        root = tree.getroot()

os.listdir(xml_folder):列出 xml_folder 中所有的文件。
if file.endswith(".xml"):只處理副檔名為 .xml 的文件。
ET.parse():解析 XML 文件並生成樹狀結構。
root:XML 樹的根節點,這裡用來尋找圖像的大小和標註的物件。

7. 讀取圖像尺寸

size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)

透過 XML 文件中的 標籤,取得圖像的 width(寬度)和 height(高度),這些數值會用於轉換邊界框的尺寸。

8. 建立對應的 TXT 文件

txt_file = os.path.join(txt_folder, file.replace('.xml', '.txt'))
with open(txt_file, 'w') as out_file:

為每個 XML 文件創建一個相應的 TXT 文件,並將其命名為與原來的 XML 文件相同,但副檔名為 .txt。
使用 open() 函數以寫入模式打開該文件。

9. 處理每個物件(bounding box)

for obj in root.iter('object'):
    cls = obj.find('name').text
    if cls not in classes:
        continue
    cls_id = classes.index(cls)
    xmlbox = obj.find('bndbox')
    b = (float(xmlbox.find('xmin').text), float(xmlbox.find('ymin').text),
         float(xmlbox.find('xmax').text), float(xmlbox.find('ymax').text))
    bbox = convert_bbox((w, h), b)
    out_file.write(f"{cls_id} {' '.join([str(a) for a in bbox])}\n")

遍歷 XML 文件中每個 標籤,這些標籤表示圖像中的物體。
取得物件的類別名稱 cls,並確認該名稱是否在預定義的 classes 清單中,如果不在則跳過。
找到類別對應的 ID (cls_id)。
取得物件的邊界框座標 ,轉換成 YOLO 格式,並寫入到對應的 TXT 文件中。

總結

這段程式碼的主要目的是自動將 Pascal VOC 格式的 XML 文件轉換為 YOLO 格式的 TXT 文件,使用者只需指定資料夾路徑和類別名稱,即可進行大批量的格式轉換。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言